package org.budo.html.editor.ue.handler;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.budo.html.editor.filter.BudoHtmlEditorFilter;
import org.budo.html.editor.handler.AbstractBudoHtmlEditorHandler;
import org.budo.support.dao.page.Page;
import org.budo.support.dao.page.PageModel;
import org.budo.support.http.client.HttpUtil;
import org.budo.support.lang.util.IoUtil;
import org.budo.support.lang.util.MapUtil;
import org.budo.support.mvcs.Mvcs;
import org.budo.time.Time;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;

/**
 * @author lmw
 */
public class UEditorHandler extends AbstractBudoHtmlEditorHandler {
    @Override
    public Boolean handleRequest(HttpServletRequest request, HttpServletResponse response, BudoHtmlEditorFilter budoHtmlEditorFilter) {
        String requestUri = request.getRequestURI();

        if (!requestUri.contains("/ue/")) {
            return false;
        }

        if (requestUri.contains("/ue/serverUrl")) {
            this.serverUrl(request, response, budoHtmlEditorFilter);
        }

        if (requestUri.contains("/ue/resources/")) {
            String resourceName = requestUri.replace("/budo-html-editor/ue/resources/", "META-INF/resources/ue/");
            return this.writeClassPathResource(resourceName, response);
        }

        return true;
    }

    private void serverUrl(HttpServletRequest request, HttpServletResponse response, BudoHtmlEditorFilter budoHtmlEditorFilter) {
        String action = request.getParameter("action");

        if ("config".equals(action)) {
            String resourceName = "META-INF/resources/ueditor-server-config-json";
            this.writeClassPathResource(resourceName, response);
            return;
        }

        if ("listfile".equals(action) //
                || "listimage".equals(action)) {
            this.listFile(request, response, budoHtmlEditorFilter);
            return;
        }

        if ("uploadimage".equals(action) //
                || "uploadvideo".equals(action) //
                || "uploadfile".equals(action)) {
            MultipartFile multipartFile = this.getFirstMultipartFile(request);
            this.uploadMultipartFile(response, budoHtmlEditorFilter, multipartFile);
            return;
        }

        if ("uploadscrawl".equals(action)) {
            this.uploadScrawl(request, response, budoHtmlEditorFilter);
            return;
        }

        if ("catchimage".equals(action)) {
            this.catchImage(request, response, budoHtmlEditorFilter);
            return;
        }
    }

    private void listFile(HttpServletRequest request, HttpServletResponse response, BudoHtmlEditorFilter budoHtmlEditorFilter) {
        Integer pageSize = Mvcs.getRequestParameterInteger(request, "start", 0);
        Integer offset = Mvcs.getRequestParameterInteger(request, "size", 20);

        Page page = new Page().setPageSize(pageSize).setOffset(offset);
        PageModel<String> urls = budoHtmlEditorFilter.listFile(page);

        Map<String, Object> map = MapUtil.stringObjectMap("state", "SUCCESS", //
                "list", urls.getList(), //
                "start", offset, //
                "total", urls.getRecordCount());

        IoUtil.write(JSON.toJSONString(map), Mvcs.getResponseOutputStream(response));
    }

    private void uploadScrawl(HttpServletRequest request, HttpServletResponse response, BudoHtmlEditorFilter budoHtmlEditorFilter) {
        String upfile = request.getParameter("upfile");

        byte[] content = Base64Utils.decode(upfile.getBytes());
        MockMultipartFile multipartFile = new MockMultipartFile("scrawl-" + Time.now().toString("yyyyMMdd-HHmmss"), content);

        this.uploadMultipartFile(response, budoHtmlEditorFilter, multipartFile);
    }

    private void catchImage(HttpServletRequest request, HttpServletResponse response, BudoHtmlEditorFilter budoHtmlEditorFilter) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

        String[] sources = request.getParameterValues("source[]");
        for (String source : sources) {
            byte[] sourceData = HttpUtil.get(source).getResponseData();

            MultipartFile multipartFile = new MockMultipartFile("scrawl-" + Time.now().toString("yyyyMMdd-HHmmss"), sourceData);
            String url = budoHtmlEditorFilter.handleMultipartFile(multipartFile);
            list.add(MapUtil.stringObjectMap("state", "SUCCESS", "source", source, "url", url));
        }

        Map<String, Object> map = MapUtil.stringObjectMap("state", "SUCCESS", "list", list);
        IoUtil.write(JSON.toJSONString(map), Mvcs.getResponseOutputStream(response));
    }

    private void uploadMultipartFile(HttpServletResponse response, BudoHtmlEditorFilter budoHtmlEditorFilter, MultipartFile multipartFile) {
        String url = budoHtmlEditorFilter.handleMultipartFile(multipartFile);

        Map<String, Object> map = MapUtil.stringObjectMap("state", "SUCCESS", //
                "url", url, //
                "original", multipartFile.getOriginalFilename(), //
                "size", multipartFile.getSize());

        IoUtil.write(JSON.toJSONString(map), Mvcs.getResponseOutputStream(response));
    }
}